home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Snippets / QuickTime / MovieToAIFF / Source / MovieToAIFF.c
Encoding:
C/C++ Source or Header  |  1996-09-17  |  9.3 KB  |  424 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        MovieToAIFF.c
  3.     
  4.     Written by:    Larry Lai, DTS
  5.  
  6.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  7.  
  8.     This app demonstrates how to use Movie Export Component    
  9.     to export QuickTime movie files into AIFF files.    
  10.     1) User interaction.
  11.     2) Export the sound with same quality.
  12.     3) Export the sound to higher quality.
  13.     
  14.     Change History (most recent first):
  15.  
  16.         <1>    3/03/95 LL    Created first version.
  17.         <2> 3/13/95    LL    Snippet candidate.
  18.         <3>    3/14/95 LL    Add code to check the sound track availability.
  19.     To Do: Check movie file type.
  20. */
  21.  
  22. #include <Memory.h>
  23. #include <Resources.h>
  24. #include <QuickDraw.h>
  25. #include <Fonts.h>
  26. #include <StandardFile.h>
  27. #include <ToolUtils.h>
  28. #include <Desk.h>
  29. #include <GestaltEqu.h>
  30. #include <Processes.h>
  31. #include <Movies.h>
  32. #include <QuickTimeComponents.h>
  33. #include <Sound.h>
  34.  
  35. #define        kAboutBox            128
  36.  
  37. #define kMyMBar 128
  38. #define kAboutBoxMenu 129
  39.  
  40. #define    movieExportUser    1
  41. #define    movieExportSame 2
  42. #define    movieExportBest    3
  43. #define    fileQuit    5
  44.  
  45. enum {
  46.     menuApple = 128,
  47.     menuFile
  48. };
  49.  
  50. void InitToolbox();
  51. void doMenuItem(long menuChoice);
  52. void exportMovieUser(void);
  53. void exportMovieSame(void);
  54. void exportMovieBest(void);
  55. MovieExportComponent openMovieExportComp(void);
  56. SampleDescriptionHandle scanSoundTracks(Movie theMovie);
  57.  
  58. Boolean        done = false;                //  true if we are ready to quit
  59. Boolean        hasSound = false;
  60.  
  61. void InitToolbox()
  62. {
  63.     InitGraf((Ptr) &qd.thePort);
  64.     InitFonts();
  65.     InitWindows();
  66.     InitMenus();
  67.     FlushEvents(everyEvent,0);
  68.     TEInit();
  69.     InitDialogs(0L);
  70.     InitCursor();
  71. }
  72.  
  73. void main()
  74. {
  75.     OSErr    err;
  76.     long    response;
  77.     EventRecord theEvent;
  78.     short i;
  79.     
  80.     InitToolbox();
  81.     
  82.     MaxApplZone(); 
  83.     
  84.     for(i = 0; i <= 10; i++)
  85.         MoreMasters();
  86.     
  87.     //Does not run under System 6
  88.     Gestalt(gestaltSystemVersion, &response);
  89.     response = (response >> 8) & 0x0f;
  90.     if ( response < 7 ) {
  91.         DebugStr("\pThis Application does not run under System 6!");
  92.         ExitToShell();
  93.     }
  94.     
  95.     // we must have QuickTime around
  96.     if (Gestalt(gestaltQuickTime, &response))
  97.         ExitToShell();
  98.  
  99.     err = EnterMovies();
  100.     if (err) 
  101.         ExitToShell();
  102.  
  103.     SetMenuBar(GetNewMBar(kMyMBar));
  104.     DrawMenuBar();
  105.  
  106.     AppendResMenu(GetMenuHandle(menuApple), 'DRVR');
  107.  
  108.     while (!done){
  109.         SystemTask();
  110.         GetNextEvent(everyEvent, &theEvent);
  111.         switch (theEvent.what) {
  112.             case mouseDown:    {
  113.                                 short part;
  114.                                 WindowPtr whichWindow;
  115.  
  116.                                 part = FindWindow(theEvent.where, &whichWindow);
  117.                                 switch (part) {
  118.                                     case inMenuBar:
  119.                                                 doMenuItem(MenuSelect(theEvent.where));
  120.                                                 break;
  121.                                     case inSysWindow:
  122.                                                 SystemClick(&theEvent, whichWindow);
  123.                                                 break;
  124.                                 }
  125.                             }
  126.                             break;
  127.  
  128.             case keyDown: {
  129.                             char c;
  130.  
  131.                             c = theEvent.message & charCodeMask;
  132.                             if (theEvent.modifiers & cmdKey)
  133.                                 doMenuItem(MenuKey(c));
  134.                             }
  135.                             break;
  136.  
  137.             default:
  138.                 break;
  139.         
  140.         }    
  141.     }
  142. }
  143.  
  144. void doMenuItem(long menuChoice)
  145. {
  146.     short whichMenu = HiWord(menuChoice);
  147.     short whichItem = LoWord(menuChoice);
  148.  
  149.     switch (whichMenu) {
  150.         case menuApple:    
  151.                     if (whichItem > 2) {
  152.                         Str255 daName;
  153.                         
  154.                         GetMenuItemText(GetMenuHandle(menuApple), whichItem, daName);
  155.                         OpenDeskAcc(daName);
  156.                     }
  157.                     else
  158.                         Alert(kAboutBox, nil);
  159.                     break;
  160.  
  161.         case menuFile:    
  162.                     switch (whichItem) {
  163.                         case movieExportUser:
  164.                                     exportMovieUser();
  165.                                     break;
  166.                         case movieExportSame:
  167.                                     exportMovieSame();
  168.                                     break;
  169.                         case movieExportBest:
  170.                                     exportMovieBest();
  171.                                     break;
  172.                         case fileQuit:
  173.                                     done = true;
  174.                                     break;
  175.                     }
  176.                     break;
  177.     }
  178.  
  179.     HiliteMenu(0);
  180.  
  181.     return;
  182. }
  183.  
  184.  
  185.  
  186. void exportMovieUser()
  187. {
  188.     OSErr err = noErr;
  189.     StandardFileReply reply;
  190.     OSType movieType = MovieFileType;
  191.     FSSpec newFile;
  192.     Point where = {100,100};
  193.     ComponentResult    result = 0;
  194.     Movie theMovie = nil;
  195.     OSType creator = 0;
  196.     short resRef;
  197.     Boolean canceled = false;
  198.     
  199.     StandardGetFilePreview(nil, 1, &movieType, &reply);
  200.     if (!reply.sfGood) return;
  201.  
  202.     // get the movie.
  203.     OpenMovieFile(&reply.sfFile, &resRef, fsRdPerm);
  204.         NewMovieFromFile(&theMovie, resRef, nil, nil,
  205.                  0, nil);
  206.     CloseMovieFile(resRef);
  207.     if (!theMovie) return;
  208.     
  209.     err = ConvertMovieToFile(theMovie, nil,&newFile, 0, 0, -1, nil, 
  210.                             showUserSettingsDialog, 0);
  211.     if (err) {
  212.         DebugStr("\p problems with Convert, may run out of disk space");
  213.         FSpDelete(&newFile);
  214.     }    
  215. }
  216.  
  217.  
  218. void exportMovieSame()
  219. {
  220.     OSErr err = noErr;
  221.     StandardFileReply reply;
  222.     OSType movieType = MovieFileType;
  223.     SFReply putFile;
  224.     FSSpec newFile;
  225.     Str255 newName;
  226.     Point where = {100,100};
  227.     MovieExportComponent exporter = 0;
  228.     SampleDescriptionHandle myDesc = NULL;
  229.     ComponentResult    result = 0;
  230.     Movie theMovie = nil;
  231.     OSType creator = 0;
  232.     short resRef;
  233.     Boolean canceled = false;
  234.     OSErr anErr = noErr;
  235.     
  236.     StandardGetFilePreview(nil, 1, &movieType, &reply);
  237.     if (!reply.sfGood) return;
  238.  
  239.     // get the movie.
  240.     OpenMovieFile(&reply.sfFile, &resRef, fsRdPerm);
  241.     NewMovieFromFile(&theMovie, resRef, nil, nil,
  242.                  0, nil);
  243.     CloseMovieFile(resRef);
  244.     if (!theMovie) return;
  245.     
  246.     BlockMove(reply.sfFile.name, newName, sizeof(reply.sfFile.name));
  247.     newName[++newName[0]] = '!';
  248.  
  249.     SFPutFile(where, "\pName sound file:", newName, nil, &putFile);
  250.     if (!putFile.good) return;
  251.  
  252.     FSMakeFSSpec(putFile.vRefNum, 0, putFile.fName, &newFile);
  253.  
  254.     myDesc = scanSoundTracks(theMovie);
  255.  
  256.     if(hasSound){
  257.         exporter = openMovieExportComp();
  258.     
  259.            result = MovieExportSetSampleDescription(exporter,myDesc,SoundMediaType); 
  260.     
  261.         if(result)
  262.             DebugStr("\pMovieExportSetSampleDescription error");
  263.  
  264.         err = ConvertMovieToFile(theMovie, nil,&newFile, 'AIFF', 'MAIF', -1, nil, 
  265.                             0, exporter);
  266.                     
  267.         if (err) {
  268.             DebugStr("\p problems with Convert, may run out of disk space");
  269.             FSpDelete(&newFile);
  270.         }    
  271.     
  272.         if(myDesc)
  273.             DisposeHandle((Handle) myDesc);
  274.         
  275.         if(exporter)
  276.             CloseComponent(exporter);
  277.         
  278.         hasSound = false;
  279.  
  280.     }
  281.     else{
  282.         DebugStr("\pCan not find any sound track in the movie.");
  283.         done = true;
  284.     }
  285.         
  286. }
  287.  
  288.  
  289. void exportMovieBest()
  290. {
  291.     OSErr err = noErr;
  292.     StandardFileReply reply;
  293.     OSType movieType = MovieFileType;
  294.     SFReply putFile;
  295.     FSSpec newFile;
  296.     Str255 newName;
  297.     Point where = {100,100};
  298.     MovieExportComponent exporter = 0;
  299.     SampleDescriptionHandle myDesc = NULL;
  300.     ComponentResult    result = 0;
  301.     Movie theMovie = nil;
  302.     OSType creator = 0;
  303.     short resRef;
  304.     Boolean canceled = false;
  305.     OSErr anErr = noErr;
  306.     SoundDescriptionHandle    mySoundDesc = nil;
  307.     
  308.     StandardGetFilePreview(nil, 1, &movieType, &reply);
  309.     if (!reply.sfGood) return;
  310.  
  311.     // get the movie.
  312.     OpenMovieFile(&reply.sfFile, &resRef, fsRdPerm);
  313.         NewMovieFromFile(&theMovie, resRef, nil, nil,
  314.                  0, nil);
  315.     CloseMovieFile(resRef);
  316.     if (!theMovie) return;
  317.     
  318.     BlockMove(reply.sfFile.name, newName, sizeof(reply.sfFile.name));
  319.     newName[++newName[0]] = '!';
  320.  
  321.     SFPutFile(where, "\pName sound file:", newName, nil, &putFile);
  322.     if (!putFile.good) return;
  323.  
  324.     FSMakeFSSpec(putFile.vRefNum, 0, putFile.fName, &newFile);
  325.     
  326.     // We don't need myDesc here, we just want to know if there is any sound track.
  327.     myDesc = scanSoundTracks(theMovie);
  328.     if(hasSound){
  329.         exporter = openMovieExportComp();
  330.        
  331.            //specify the data format.
  332.         mySoundDesc = (SoundDescriptionHandle)NewHandleClear(sizeof(SoundDescription));
  333.         (**mySoundDesc).descSize = sizeof(SoundDescription);
  334.         (**mySoundDesc).dataFormat = 'twos';
  335.         (**mySoundDesc).dataRefIndex = 1;
  336.         (**mySoundDesc).numChannels = 2;
  337.         (**mySoundDesc).sampleSize = 16;
  338.         (**mySoundDesc).sampleRate = 0xAC440000;    
  339.     
  340.            result = MovieExportSetSampleDescription(exporter,(SampleDescriptionHandle)mySoundDesc,SoundMediaType); 
  341.     
  342.         if(result)
  343.             DebugStr("\pMovieExportSetSampleDescription error");
  344.     
  345.         err = ConvertMovieToFile(theMovie, nil,&newFile, 'AIFF', 'MAIF', -1, nil, 
  346.                             0, exporter);
  347.                     
  348.         if (err) {
  349.             DebugStr("\p problems with Convert, may run out of disk space");
  350.             FSpDelete(&newFile);
  351.         }    
  352.     
  353.         if(myDesc)
  354.             DisposeHandle((Handle) myDesc);
  355.         if(mySoundDesc)
  356.             DisposeHandle((Handle) mySoundDesc);
  357.             
  358.         if(exporter)
  359.             CloseComponent(exporter);
  360.         
  361.         hasSound = false;
  362.     }
  363.     else{
  364.         DebugStr("\pCan not find any sound track in the movie.");
  365.         done = true;
  366.     }
  367. }
  368.  
  369.  
  370. SampleDescriptionHandle scanSoundTracks(Movie theMovie)
  371. {
  372.     short trackCount, index;
  373.     SampleDescriptionHandle aDesc = NULL;
  374.     OSErr    anErr;
  375.     
  376.        //find the first sound track. Since 2.0 all the sound are mixed together.
  377.     trackCount = GetMovieTrackCount(theMovie);
  378.     for(index = 1; index <= trackCount; index++)
  379.     {
  380.         OSType     aTrackType;
  381.         Track    aTrack = NULL;
  382.         Media    aMedia = NULL;
  383.         
  384.         //I did not check error, but you should.
  385.         aTrack = GetMovieIndTrack(theMovie, index); 
  386.         aMedia = GetTrackMedia(aTrack);
  387.         
  388.         GetMediaHandlerDescription(aMedia, &aTrackType, 0, 0);
  389.         if(aTrackType == SoundMediaType)
  390.         {
  391.             hasSound = true;
  392.             aDesc = (SampleDescriptionHandle)NewHandle(sizeof(SampleDescription));
  393.             GetMediaSampleDescription(aMedia, 1, aDesc);
  394.             anErr = GetMoviesError();
  395.             if(anErr != noErr)
  396.             {
  397.                 DisposeHandle((Handle)aDesc);
  398.                 continue;
  399.             }
  400.         }
  401.     }
  402.     return    aDesc;
  403.     
  404. }
  405.     
  406. MovieExportComponent openMovieExportComp()
  407. {
  408.     MovieExportComponent soundComp;
  409.     Component c;
  410.     ComponentDescription cd;
  411.         
  412.     // specify the export component
  413.     cd.componentType = MovieExportType;
  414.     cd.componentSubType = 'AIFF';
  415.     cd.componentManufacturer = 0;
  416.     cd.componentFlags = canMovieExportFiles;
  417.     cd.componentFlagsMask = canMovieExportFiles;
  418.     c = FindNextComponent(nil, &cd);
  419.  
  420.     if (!c) DebugStr("\pcan not find component");                        // too weird. no export component exists
  421.         soundComp = nil;
  422.     soundComp = OpenComponent(c);
  423.     return    soundComp;
  424. }